package com.lucifer.treasure.enchant.effect;

import com.lucifer.treasure.registry.EnchantRegistry;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3d;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public record MultiJumpEnchantmentEffect(EnchantmentLevelBasedValue jumps) implements EnchantmentEntityEffect {
    public static final MapCodec<MultiJumpEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("jumps").forGetter(MultiJumpEnchantmentEffect::jumps)
            ).apply(instance, MultiJumpEnchantmentEffect::new)
    );

    // 网络包标识符
    public static final Identifier MULTIJUMP_PACKET_ID = Identifier.of("lucifer_treasure", "multijump");

    // NBT标签
    private static final String NBT_JUMP_USES = "lucifer_treasure_jump_uses";
    private static final String NBT_LAST_GROUND_TIME = "lucifer_treasure_last_ground_time";

    // 配置常量
    private static final int COOLDOWN_TICKS = 140; // 7秒冷却
    private static final float JUMP_POWER = 0.8f;
    private static final int MAX_AIR_TIME = 10; // 最大空中时间才能跳跃

    // 服务端验证数据存储
    private static final Map<UUID, PlayerJumpData> playerJumpData = new HashMap<>();

    // 玩家跳跃数据类
    private static class PlayerJumpData {
        int jumpsUsed = 0;
        long lastGroundTime = 0;
        boolean wasOnGround = true;

        PlayerJumpData() {
        }
    }

    public static void initialize() {
        // 注册网络包处理 - 在客户端处理

        // 服务器tick事件，用于重置地面状态
        ServerTickEvents.END_SERVER_TICK.register(server -> {
            // 首先检查配置是否启用此附魔
            if (!EnchantRegistry.isEnchantEnabled("multijump")) {
                return;
            }
            server.getPlayerManager().getPlayerList().forEach(player -> {
                updatePlayerJumpState(player);
            });
        });
    }

    /**
     * 更新玩家跳跃状态（服务端验证）
     */
    private static void updatePlayerJumpState(ServerPlayerEntity player) {
        UUID playerId = player.getUuid();
        PlayerJumpData data = playerJumpData.computeIfAbsent(playerId, k -> new PlayerJumpData());

        // 检查玩家是否在地面
        boolean isOnGround = player.isOnGround();

        // 如果刚落地，重置跳跃次数
        if (isOnGround && !data.wasOnGround) {
            data.jumpsUsed = 0;
            data.lastGroundTime = player.getWorld().getTime();
        }

        data.wasOnGround = isOnGround;

        // 验证玩家的多重跳跃附魔等级
        int maxJumps = getMultiJumpLevel(player);
        if (maxJumps <= 0) {
            data.jumpsUsed = 0; // 没有附魔时重置
        }
    }

    /**
     * 验证并执行多重跳跃（供客户端调用验证）
     */
    public static boolean validateAndPerformJump(ServerPlayerEntity player) {
        UUID playerId = player.getUuid();
        PlayerJumpData data = playerJumpData.computeIfAbsent(playerId, k -> new PlayerJumpData());

        // 基础检查
        if (player.isOnGround() ||
                player.isTouchingWater() ||
                player.hasVehicle() ||
                player.getAbilities().flying ||
                player.isSpectator()) {
            return false;
        }

        // 检查是否在下降
        if (player.getVelocity().y >= 0) {
            return false;
        }

        // 检查多重跳跃等级
        int maxJumps = getMultiJumpLevel(player);
        if (maxJumps <= 0) {
            return false;
        }

        // 检查跳跃次数
        if (data.jumpsUsed >= maxJumps) {
            return false;
        }

        // 执行跳跃
        Vec3d velocity = player.getVelocity();
        player.setVelocity(velocity.x, 0.8, velocity.z);
        player.fallDistance = 0;

        // 更新跳跃次数
        data.jumpsUsed++;

        return true;
    }

    /**
     * 获取玩家的多重跳跃等级
     */
    private static int getMultiJumpLevel(PlayerEntity player) {
        int maxLevel = 0;

        // 检查所有护甲槽位
        for (ItemStack armorStack : player.getArmorItems()) {
            if (!armorStack.isEmpty()) {
                int level = getMultiJumpLevelFromStack(armorStack);
                maxLevel = Math.max(maxLevel, level);
            }
        }

        return maxLevel;
    }

    /**
     * 从物品栈获取MultiJump附魔等级
     */
    private static int getMultiJumpLevelFromStack(ItemStack stack) {
        if (stack.isEmpty()) {
            return 0;
        }

        var enchantments = EnchantmentHelper.getEnchantments(stack);
        return enchantments.getEnchantments().stream()
                .filter(entry -> {
                    if (entry.getKey().isPresent()) {
                        return entry.getKey().get().getValue().toString().equals("lucifer_treasure:multijump");
                    }
                    return false;
                })
                .mapToInt(entry -> enchantments.getLevel(entry))
                .max()
                .orElse(0);
    }

    /**
     * 清理离线玩家数据
     */
    public static void cleanupPlayerData(UUID playerId) {
        playerJumpData.remove(playerId);
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 服务端验证逻辑，确保联机时的一致性
        if (target instanceof ServerPlayerEntity player) {
            updatePlayerJumpState(player);
        }
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 